package me.zhengjie.wcs;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.zhengjie.config.PPNetConfig;
import me.zhengjie.modbusTCP.EntranceTCP;
import me.zhengjie.ppService.PPTaskResultService;
import me.zhengjie.pojo.Request;
import me.zhengjie.pojo.Response;
import me.zhengjie.pojo.StorageReport;
import me.zhengjie.pojo.sqlServer.*;
import me.zhengjie.repository.*;
import me.zhengjie.util.UniqueCodeUtil;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.transaction.Transactional;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Component
@RequiredArgsConstructor
public class PPWmsToWcs {

    private final PPInboundMissionRepository  ppInboundMissionRepository;
    private final PPInboundMissionHistoryRepository ppInboundMissionHistoryRepository;
    private final PPOutboundMissionRepository  ppOutboundMissionRepository;
    private final PPOutboundMissionHistoryRepository ppOutboundMissionHistoryRepository;
    private final PPNetConfig ppNetConfig;
    private final PPTaskResultService ppTaskResultService;
    private final PPMoveMissionRepository ppMoveMissionRepository;
    private final PPMoveMissionHistoryRepository ppMoveMissionHistoryRepository;
    private final EntranceTCP entranceTCP;
    private  final PPStationRepository ppStationRepository;

    private static final Logger ppLog = LoggerFactory.getLogger("pp");


    /**
     * 向wcs发送容器任务
     * @param wmsTask 容器任务
     * @return 响应结果
     */
    public Response sendTask(PPWmsTask wmsTask){
        // 拼接URL
        String WCS_URL = new StringBuilder()
                .append("http://")
                .append(ppNetConfig.getWcsIp())
                .append(":")
                .append(ppNetConfig.getWcsPort())
                .append(ppNetConfig.getTaskUrl())
                .toString();

        Request request = new Request();
        request.setMessageId(UniqueCodeUtil.createCode());
        request.setMessageTime(String.valueOf(new Date().getTime()));
        request.setMessageType("containerTask");
        request.setMessageDesc("容器任务下发");
        request.setData(wmsTask);
        try {
            ObjectMapper objectMapper = new ObjectMapper();
            // 将wcsRequest转为json格式
            String jsonBody = objectMapper.writeValueAsString(request);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);
            // 将响应体转为wcsResponse
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> responseEntity = restTemplate.postForEntity(WCS_URL, requestEntity, String.class);
            String responseBody = responseEntity.getBody();
            Response response =  objectMapper.readValue(responseBody, Response.class);
            if (ObjectUtils.isEmpty(response)){
                log.error("发送任务到wcs响应为空");
                throw new RuntimeException("发送任务到wcs响应为空");
            }

            if (response.getIsSuccess()==0){
                //任务下发失败
                log.error("发送任务到wcs失败,失败原因{}",response.getErrorMsg());
                throw new RuntimeException("发送任务到wcs失败,失败原因"+response.getErrorMsg());
            }

            //入库任务
            if (wmsTask.getWcsTaskType()==1){//入库任务

                //todo 切换工作站的模式
                PPStation ppStation = ppStationRepository.findByStationCode(wmsTask.getFromLocation());
                entranceTCP.write(ppStation.getAddress(),1,5);
                ppLog.info("工作站{}切换模式为入库",ppStation.getStationCode());
                //输出到控制台
                log.info("收到入库任务反馈,切换工作站的模式为入库");

                //先判断是否有货
                if (entranceTCP.readHoldingRegisters(ppStation.getTakeAddress())==1){
                    //有货
                    //启动回流线
                    entranceTCP.write(ppStation.getStartAddress(),1,5);
                    log.info("工作站{}启动回流线",ppStation.getStationCode());
                }else {
                    //无货
                    log.error("工作站{}回流线无货,启动回流线失败,任务终止",ppStation.getStationCode());
                    throw  new RuntimeException("工作站无货,启动回流线失败,任务终止");
                }

                // 创建任务状态
                saveTaskResult(wmsTask);
                // 存储到历史任务表中
                saveToMissionHistory(wmsTask,1);

                ppInboundMissionRepository.deletePPInboundMissionByMissionCode(String.valueOf(wmsTask.getWmsTaskId()));
            }else if(wmsTask.getWcsTaskType()==2){ //出库任务

                // 创建任务状态
                saveTaskResult(wmsTask);
                // 存储到历史任务表中
                saveToMissionHistory(wmsTask,2);
                // 删除任务，任务状态。
                ppOutboundMissionRepository.deletePPOutboundMissionByMissionCode(wmsTask.getWmsTaskId());


            }else if(wmsTask.getWcsTaskType()==3) { //移库任务

                //创建任务状态
                saveTaskResult(wmsTask);
                // 存储到历史任务表中
                saveToMissionHistory(wmsTask,3);

            }

            return response;
        } catch (Exception e) {
            ppLog.error("发送任务到wcs失败，失败原因: {}", e.getMessage(), e);
            return null;
        }
    }

    /**
     * 向wcs发送储位信息
     *
     * @param storageList 储位信息
     */
    public void sendStorage(List<PPStorage> storageList){
        // 拼接URL
        String WCS_URL = new StringBuilder()
                .append("http://")
                .append(ppNetConfig.getWcsIp())
                .append(":")
                .append(ppNetConfig.getWcsPort())
                .append(ppNetConfig.getStorageUrl())
                .toString();
        ppLog.info("同步储位接口：{}",WCS_URL);
        Request request = new Request();
        request.setMessageId(UniqueCodeUtil.createCode());
        request.setMessageTime(String.valueOf(new Date().getTime()));
        request.setMessageType("dicLocation");
        request.setMessageDesc("货位信息下发");

        List<StorageReport> storageReports = storageList.stream().map(x -> new StorageReport(x.getId(),x.getStorageCode(),x.getLogicalAddressType(),x.getZoneCode(),x.getAisle(),x.getLayer(),x.getRow(),x.getColumn(),x.getLocationInventoryStatus(),x.getStatus())).collect(Collectors.toList());

        request.setData(storageReports);
        ObjectMapper objectMapper = new ObjectMapper();
        try {

            // 将wcsRequest转为json格式
            String jsonBody = objectMapper.writeValueAsString(request);
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);
            HttpEntity<String> requestEntity = new HttpEntity<>(jsonBody, headers);
            // 将响应体转为wcsResponse
            RestTemplate restTemplate = new RestTemplate();
            restTemplate.postForEntity(WCS_URL, requestEntity, String.class);
            /* ResponseEntity<String> responseEntity = restTemplate.postForEntity(WCS_URL, requestEntity, String.class);
            String responseBody = responseEntity.getBody();
            objectMapper.readValue(responseBody, Response.class);*/
        } catch (Exception e) {
            ppLog.error("发送储位信息到wcs失败,失败原因:{}", e.toString());
        }
    }

    public void saveToMissionHistory(PPWmsTask wmsTask,int taskType){
        try {
            if (taskType == 1){
                PPInboundMission inBoundMission =  ppInboundMissionRepository.findPPInboundMissionByMissionCode(String.valueOf(wmsTask.getWmsTaskId()));
                PPInboundMissionHistory inBoundMissionHistory = new PPInboundMissionHistory();
                inBoundMissionHistory.setMissionCode(inBoundMission.getMissionCode());
                inBoundMissionHistory.setPalletCode(inBoundMission.getPalletCode());
                inBoundMissionHistory.setMissionStatus("任务创建");
                inBoundMissionHistory.setSource(inBoundMission.getSource());
                inBoundMissionHistory.setDestination(inBoundMission.getDestination());
                inBoundMissionHistory.setCreateTime(inBoundMission.getCreateTime());
                inBoundMissionHistory.setStartTime(inBoundMission.getStartTime());
                inBoundMissionHistory.setPpId(inBoundMission.getPpId());
                inBoundMissionHistory.setPpQty(inBoundMission.getPpQty());
                ppInboundMissionHistoryRepository.save(inBoundMissionHistory);
                ppLog.info("保存入库历史任务成功");
            }else if (taskType == 2){
                PPOutboundMission outBoundMission = ppOutboundMissionRepository.findPPOutboundMissionByMissionCode(String.valueOf(wmsTask.getWmsTaskId()));
                PPOutboundMissionHistory outBoundMissionHistory = new PPOutboundMissionHistory();
                outBoundMissionHistory.setMissionCode(outBoundMission.getMissionCode());
                outBoundMissionHistory.setPalletCode(outBoundMission.getPalletCode());
                outBoundMissionHistory.setMissionStatus("任务创建");
                outBoundMissionHistory.setSource(outBoundMission.getSource());
                outBoundMissionHistory.setDestination(outBoundMission.getDestination());
                outBoundMissionHistory.setCreateTime(outBoundMission.getCreateTime());
                outBoundMissionHistory.setStartTime(outBoundMission.getStartTime());
                outBoundMissionHistory.setPpId(outBoundMission.getPpId());
                outBoundMissionHistory.setPpQty(outBoundMission.getPpQty());
                ppOutboundMissionHistoryRepository.save(outBoundMissionHistory);
                ppLog.info("保存出库历史任务成功");
            }else if(taskType == 3){
                PPMoveMission ppMoveMission = ppMoveMissionRepository.findPPMoveMissionByMissionCode(String.valueOf(wmsTask.getWmsTaskId()));
                PPMoveMissionHistory ppMoveMissionHistory = new PPMoveMissionHistory();
                ppMoveMissionHistory.setMissionCode(ppMoveMission.getMissionCode());
                ppMoveMissionHistory.setPalletCode(ppMoveMission.getPalletCode());
                ppMoveMissionHistory.setMissionStatus("任务创建");
                ppMoveMissionHistory.setSource(ppMoveMission.getSource());
                ppMoveMissionHistory.setDestination(ppMoveMission.getDestination());
                ppMoveMissionHistory.setCreateTime(ppMoveMission.getCreateTime());
                ppMoveMissionHistory.setStartTime(ppMoveMission.getStartTime());
                ppMoveMissionHistoryRepository.save(ppMoveMissionHistory);
                ppLog.info("保存移库历史任务成功");


            }
        } catch (Exception e) {

            ppLog.error("保存历史任务失败：{}",e.toString());
        }
    }



    public void saveTaskResult(PPWmsTask wmsTask){
        PPTaskResult taskResult = new PPTaskResult();
        taskResult.setWmsTaskId(wmsTask.getWmsTaskId());
        taskResult.setWcsTaskType(wmsTask.getWcsTaskType());
        taskResult.setLpnCode(wmsTask.getLpnCode());
        taskResult.setFromLocation(wmsTask.getFromLocation());
        taskResult.setToLocation(wmsTask.getToLocation());
        taskResult.setCreated(LocalDateTime.now());
        taskResult.setStatus(0);
        ppTaskResultService.saveTaskResult(taskResult);
    }


}
